Skip to content

ci/nightly: manifest aggregator + 90-build retention sweep#2112

Merged
widgetii merged 1 commit into
masterfrom
ci/nightly-manifest-and-cleanup
May 20, 2026
Merged

ci/nightly: manifest aggregator + 90-build retention sweep#2112
widgetii merged 1 commit into
masterfrom
ci/nightly-manifest-and-cleanup

Conversation

@widgetii
Copy link
Copy Markdown
Member

Summary

PR-B of six in the nightly-build redesign. Adds the two workflows that turn the dated nightly-* releases from #2111 into a queryable index served via GitHub Pages.

  • manifest.yml — triggers on successful build.yml completion (or manual dispatch). Runs .github/scripts/enrich_manifest.py to enumerate dated releases, keep the 90 newest, parse the body (sha=/short=/built_at= from ci/nightly: SHA-gate cron, publish dated nightly-* releases, BUILD_ID in os-release #2111) and asset list, then emit:
    • manifest.json — rich JSON for hosts/agents/CI.
    • manifest.flat — whitespace-delimited, parseable by pure busybox awk (no jq or jsonfilter) for on-device sysupgrade in PR-C.
    • Both committed to the gh-pages branch.
  • cleanup.yml — Mondays 05:00 UTC. Deletes dated nightly releases beyond the 90 newest via gh release delete --cleanup-tag, then re-triggers manifest.yml.
  • concurrency: gh-pages-manifest serializes both workflows so concurrent runs cannot race the gh-pages push.

URLs after merge

(gh-pages branch and Pages site are already configured, pointing at gh-pages / /.)

Schema notes

  • md5 is intentionally omitted from v1. Each .tgz already ships a .md5sum sidecar that sysupgrade validates after download (general/overlay/usr/sbin/sysupgrade:93-95), so manifest-level md5 would be redundant and would require downloading every asset on each rebuild.
  • manifest.flat columns: build_id platform flash size url. Lines starting with # are comments; @channel <name> <build_id> records pin channels. awk '$1==build && $2==plat && $3==flash {print $NF}' is the entire on-device lookup.

First-run behaviour

When no dated nightly-* releases exist yet, the script writes an explicit empty manifest with a "first cron will populate" comment. Already validated locally against the live repo — the empty path works.

Test plan

  • CI on this PR passes (no jobs to actually run; only YAML lint + script compile via the matrix's own gcc-compat checks if applicable).
  • After merge, manually dispatch manifest.yml once; it should write an empty manifest to gh-pages (no dated releases exist yet).
  • Tonight's first cron after merge: build.yml completes → publishes nightly-YYYYMMDD-<short>workflow_run triggers manifest.yml → manifest emerges with one build entry.
  • curl https://openipc.github.io/firmware/manifest.json | jq '.channels.nightly' returns the just-published build_id.
  • curl https://openipc.github.io/firmware/manifest.flat | awk '\$1==\"<id>\" && \$2==\"hi3520dv200_lite\" && \$3==\"nor\" {print \$NF}' returns the asset URL.
  • Manually dispatch cleanup.yml — no-op while ≤90 dated releases exist.

🤖 Generated with Claude Code

Adds the two CI workflows that turn the dated nightly-* releases from
PR #2111 into a queryable index served via GitHub Pages.

manifest.yml — triggers on successful completion of build.yml (or by
manual dispatch). Runs general/scripts/.../enrich_manifest.py to:
- enumerate up to 200 GH releases, keep tags matching
  ^nightly-[0-9]{8}-[0-9a-f]{7}$, sort newest first, keep top 90;
- for each, parse the body (sha=/short=/built_at= written by PR #2111)
  and the assets list, mapping openipc.<soc>-<flash>-<variant>.tgz
  to platforms.<soc>_<variant>.<flash>;
- emit manifest.json (rich, JSON, for hosts/agents/CI) and
  manifest.flat (whitespace-delimited, for busybox sysupgrade);
- commit both to the gh-pages branch.

Resulting URLs:
- https://openipc.github.io/firmware/manifest.json
- https://openipc.github.io/firmware/manifest.flat

cleanup.yml — Monday 05:00 UTC + workflow_dispatch. Deletes every
dated nightly release beyond the 90 newest via `gh release delete
--cleanup-tag`, then re-triggers manifest.yml to drop those entries
from the index.

A concurrency group `gh-pages-manifest` serializes the manifest and
cleanup workflows so concurrent runs cannot race the gh-pages push.

md5 is intentionally absent from the v1 schema — each .tgz already
ships a .md5sum sidecar that sysupgrade validates after download, so
a manifest-level md5 would be redundant and would require downloading
every asset on each rebuild. The flat schema is therefore 5 columns:
build_id platform flash size url.

First-run behaviour: when no dated nightly-* releases exist yet,
enrich_manifest writes an explicit empty manifest with a "first cron
will populate" comment. Verified locally against the live repo.

PR-B of six in the nightly-build redesign. Depends on PR #2111
(merged) for the dated release tag format. The gh-pages branch and
Pages site are already configured.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant